/*****************************
Last Modified: 2022/06/22
    =======================================
     [时间] | [级别] | [位置(文件+函数名)]: | 信息
     [22/06/22 06:45:11.111] | [DEBUG] | [lflog.c:create_log]; | Create log:/var/log/debug.log
    =======================================
 *****************************/

#ifndef __LFLOG_H__
#define __LFLOG_H__

#ifdef __cplusplus
extern "C"{
#endif

/**
 * @brief 定义一行日志缓存大小
 *
 * @note 如果需要输出的日志信息比较长，超过 MAX_FLOG_BUFFER_LEN 可能出现截断
 */
#define MAX_FLOG_BUFFER_LEN  1024

#ifdef WIN32
#define LFLOG_DIR    "./"
#else
#define LFLOG_DIR    "/var/log/"
#endif

typedef enum __lflog_level{
    LFLOG_NONE,
    LFLOG_DEBUG,
    LFLOG_INFO,
    LFLOG_WARNING,
    LFLOG_ERROR,
    LFLOG_CRITICAL,
    LFLOG_MAX
}LFLogLevel;

typedef struct __lflog* LFLog;

/**
 * @brief   创建一个日志.
 *
 * @param   logfile 指定日志输出文件名.
 *          可以是 NULL ，WIN 系统默认 "./lflog.log"
 *          linux 系统默认 "/var/log/lflog.log"
 *
 * @param   level 设定最低日志输出等级.
 *
 * @return  返回创建的日志句柄.
 */
LFLog create_lflog(const char *logfile, LFLogLevel level);

/**
 * @brief   销毁一个日志.
 *
 * @param   log 需要销毁的日志.
 *
 * @note    销毁日志，但是不删除日志记录.
 */
void destroy_lflog(LFLog log);

/**
 * @brief   修改最低日志输出等级.
 *
 * @param   log 指定日志.
 *
 * @param   level 指定新的最低日志输出等级.
 *
 * @note    可在程序运行期间改变输出等级.
 */
void change_lflog_level(LFLog log, LFLogLevel level);

/**
 * @brief   记录日志.
 *
 * @param   log 指定日志.
 *
 * @param   level 设定日志记录等级.
 *
 * @param   file 日志记录行所在源程序文件名，可自行用其它任意字符串，或者空.
 *
 * @param   function 日志记录行所在函数名，可改成其它任意字符串，或者空.
 *
 * @param   fmt 格式化字符串，参照 printf.
 *
 * @note    记录日志的唯一 api，由此可以扩展下面多种宏定义.
 */
void lflog(LFLog log, LFLogLevel level, const char *file, const char *function, const char *fmt, ...);

#define lFLog(log, level, fmt, arg...) lflog(log, level, __FILE__, __FUNCTION__, fmt, ##arg)

#define lFLog_Debug(log, fmt, arg...) lflog(log, LFLOG_DEBUG, __FILE__, __FUNCTION__, fmt, ##arg)
#define lFLog_Info(log, fmt, arg...) lflog(log, LFLOG_INFO, __FILE__, __FUNCTION__, fmt, ##arg)
#define lFLog_Warning(log, fmt, arg...) lflog(log, LFLOG_WARNING, __FILE__, __FUNCTION__, fmt, ##arg)
#define lFLog_Error(log, fmt, arg...) lflog(log, LFLOG_ERROR, __FILE__, __FUNCTION__, fmt, ##arg)
#define lFLog_Critical(log, fmt, arg...) lflog(log, LFLOG_CRITICAL, __FILE__, __FUNCTION__, fmt, ##arg)

#ifdef __cplusplus
}
#endif

#endif // __LFLOG_H__
